package calculator.equationnodes;

/*
 * FuncNode.java
 * Author: Ben McCormick
 * Written: Jan 2 2011
 * Last Edited: June 27 2011
 * Ben McCormick 2011
 * This file is part of The Eikona Project .
 *    Copyright 2011 Ben McCormick
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *    
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 */

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Random;

public class FuncNode extends OpNode {

	boolean radians;
	
	public FuncNode(String func,boolean rad)
	{
		name = func;
		type = "f";
		radians = rad;
	}
	public BigDecimal getValue() {  //should put this in order of most likely to least likely to be used
		if(name.equals("sin("))
		{
			if(radians)
			return new BigDecimal(Math.sin(child.getValue().floatValue()));
			else
				return new BigDecimal(Math.sin(Math.toRadians(child.getValue().floatValue())));
		}
		if(name.equals("cos("))
		{
			if(radians)
			return new BigDecimal(Math.cos(child.getValue().floatValue()));
			else
				return new BigDecimal(Math.cos(Math.toRadians(child.getValue().floatValue())));
		}
		if(name.equals("tan("))
		{
			if(radians)
			return new BigDecimal(Math.tan(child.getValue().floatValue()));
			else
				return new BigDecimal(Math.tan(Math.toRadians(child.getValue().floatValue())));
		}
		if(name.equals("asin("))
		{
			if(radians)
				return new BigDecimal(Math.asin(child.getValue().floatValue()));
				else
					return new BigDecimal(Math.toDegrees(Math.asin(child.getValue().floatValue())));
		}
		if(name.equals("acos("))
		{
			if(radians)
				return new BigDecimal(Math.acos(child.getValue().floatValue()));
				else
					return new BigDecimal(Math.toDegrees(Math.acos(child.getValue().floatValue())));
		}
		if(name.equals("atan("))
		{
			if(radians)
				return new BigDecimal(Math.atan(child.getValue().floatValue()));
				else
					return new BigDecimal(Math.toDegrees(Math.atan(child.getValue().floatValue())));
		}
		if(name.equals("abs("))
		{
			return child.getValue().abs();
		}
		if(name.equals("sqr("))
		{
			return child.getValue().multiply(child.getValue());
		}
		if(name.equals("sqrt("))
		{
			double x = Math.sqrt(child.getValue().floatValue());
			return new BigDecimal(x);
		}
		if(name.equals("log(")) //needs to be fixed
		{
			return new BigDecimal((Math.log(child.getValue().floatValue())/Math.log(10.0)));
		}
		if(name.equals("ln("))
		{
			return new BigDecimal(Math.log(child.getValue().floatValue()));
		}
		if(name.equals("exp("))
		{
			return new BigDecimal(Math.pow(Math.E,child.getValue().doubleValue()));
		}
		if(name.equals("ceil("))
		{
			BigDecimal x = child.getValue();
			x=new BigDecimal(x.intValue()+1);
			return x;
		}
		if(name.equals("floor("))
		{
			BigDecimal x = child.getValue();
			x=new BigDecimal(x.intValue());
			return x;
		}
		if(name.equals("neg("))
		{
			return (new BigDecimal(0)).subtract(child.getValue());
		}
		if(name.equals("rnd("))
		{
			Random r = new Random(child.getValue().longValue());
			return new BigDecimal(r.nextDouble());
		}
		if(name.equals("("))
		{
			return (child.getValue());
		}
		else
		{
			//Throw exception??
			return new BigDecimal(0);
		}
	}
	
	public String toString()
	{
		if(child != null)
		return name+child.toString()+")";
		
		return name;
	}
	
	
	public int getPriority() {
		// TODO Auto-generated method stub
		return 10;
	}

}
